#pragma once

#include <windows.h>

#define TAppID _GUID
#define TGradeAddr _GUID
#define TGenericID _GUID


const GUID GradeAddrNone = {0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } };
const GUID GradeAddrAny  = {0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };

const int InjectMaxTTL = 0;     //use this constant to inject capsules with max. TTL

//error codes
#define  geNoError         0
#define  geUnknownError   -1
#define  geTargetNotFound  1
#define  geNoListener      2

const GUID IID_INeighborTable = {0x73858BFB, 0x9E1D, 0x42F0, { 0x99, 0xE4, 0x7C, 0xBB, 0x8F, 0x0A, 0x34, 0x8B } };
const GUID IID_IStates = {0x6CB929BD, 0x635F, 0x4831, { 0x85, 0xF0, 0xA3, 0x32, 0x05, 0x64, 0x2D, 0x57 } };
const GUID IID_IRoutingTable = {0xD93ADAB0, 0xEDD4, 0x4BC8, { 0xAC, 0xE4, 0x1B, 0xAA, 0xD3, 0x7C, 0x9D, 0xBE } };
const GUID IID_IServer = {0x560A60B4, 0x587F, 0x42B0, { 0xAD, 0x5A, 0x42, 0x75, 0x5C, 0xA9, 0x11, 0xFA } };
const GUID IID_ILogger = {0xBBDB259D, 0x736F, 0x4D72, { 0xBE, 0x89, 0xFA, 0xC6, 0xD9, 0xEB, 0x52, 0x6B } };
const GUID IID_IListener = {0x885A26B0, 0x832B, 0x4E93, { 0xB2, 0x3B, 0x1E, 0x1D, 0xF4, 0x7A, 0x60, 0xF7 } };
const GUID IID_IBaseEEAPI = {0x9CE17014, 0xD097, 0x43A6, { 0x85, 0x5A, 0xD8, 0xDD, 0x1D, 0xAB, 0x45, 0x9E } };
const GUID IID_IRunnable = {0x220A65DE, 0xE0AA, 0x42D8, { 0xA1, 0x3E, 0x36, 0x02, 0xB3, 0xA0, 0xF9, 0xA8 } };
const GUID IID_IAppAPI = {0x67B76624, 0xF297, 0x4D50, { 0xAD, 0xB9, 0x38, 0x44, 0xFD, 0x05, 0xAE, 0x7A } };
const GUID IID_ICapsuleAPI = {0xDB017620, 0x8DC3, 0x40AC, { 0xA4, 0xDD, 0xCE, 0x87, 0xD1, 0x3C, 0xA6, 0xC2 } };


typedef struct _PerformanceSnapshot {
	DWORD Benchmark;			//higher value means higher power
	int CPUsNum;				//number of processors we run on    
								//all values below are average ones
	double AvgCPUUsage;			//represents all of processors
	double AvgCPULowestUsage;	//always for the least loaded processor
	double AvgEEs;
	double AvgAvailPhysMem;
} TPerformanceSnapshot;


__interface INeighborTable : public IUnknown {
public:
     TGradeAddr __stdcall Neighbors(int AnIndex) = 0;
     int __stdcall NeighborCount() = 0;
};

__interface IStates : public IUnknown {
public:
     HRESULT __stdcall AcquireState(TGenericID AState, IStream** AStream) = 0;
     void __stdcall ReleaseState(TGenericID AState) = 0;
};


__interface IRoutingTable : public IUnknown {
public:
     HRESULT __stdcall GetNeighborTable(INeighborTable** ATable) = 0;
     TGradeAddr __stdcall GetNextNode(TGradeAddr ADest) = 0;
     HRESULT __stdcall UpdatePath(TGradeAddr ADest, TGradeAddr AGateway) = 0;
     HRESULT __stdcall GetPath(int AnIndex, TGradeAddr* ADest, TGradeAddr AGateway) = 0;
     int __stdcall PathCount() = 0;
};

__interface IServer : public IUnknown {
public:
     HRESULT __stdcall GetRoutingTable(IRoutingTable** ATable) = 0;
     TGradeAddr __stdcall Address() = 0;
     TPerformanceSnapshot __stdcall PerformanceSnapshot() = 0;
     HRESULT __stdcall States(IStates** AStates) = 0;
};


__interface ILogger : public IUnknown {
public:
	 void __stdcall LogString(char* AStr) = 0;
};


__interface IListener : public IUnknown {
public:
     void __stdcall OnSendData(TAppID Sender, IStream* Data) = 0;
};


__interface IBaseEEAPI : public IUnknown {
public:
   TAppID __stdcall GetID() = 0;
   void __stdcall RegisterListener(IListener* AListener) = 0;
   HRESULT __stdcall CreateStream(IStream** AStream) = 0;
   HRESULT __stdcall GetServer(IServer** AServer) = 0;
   HRESULT __stdcall GetLogger(ILogger** ALogger) = 0;
   HRESULT __stdcall GetDataLoad(IStream** AStream) = 0;
   int __stdcall InjectCapsule(char* AFriendlyCodeName,
                                      IStream* ADataLoad,
                                      TGradeAddr ADest,
                                      int ATTL) = 0;
   int __stdcall InjectApplication(char *AFriendlyCodeName,
                                          IStream* ADataLoad,
                                          TGradeAddr ACodeSource) = 0;
   HANDLE __stdcall LoadLibrary(char* AFriendlyCodeName,
                                       TGradeAddr ACodeSource) = 0;
   int __stdcall SendData(TAppID ATarget, IStream* AData) = 0;
};

__interface IRunnable : public IUnknown {
public:
	 void __stdcall Execute() = 0;
};

__interface IAppAPI  : public IBaseEEAPI {
public:
   void __stdcall ExecuteThread(IRunnable *AThread) = 0;
   TAppID __stdcall AddAnotherListener(IListener* AListener) = 0;
   void __stdcall RemoveListener(TAppID AnAppID) = 0;
   double __stdcall AverageCPUUtil() = 0;
};

__interface ICapsuleAPI : public IBaseEEAPI {
public:
    TGradeAddr __stdcall GetSrc() = 0;
    TGradeAddr __stdcall GetDst() = 0;
    void __stdcall SetDst(TGradeAddr ADst) = 0;
    int __stdcall GetTTL() = 0;
    void __stdcall Finish() = 0;
};